home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / sml_nj / 93src.lha / src / rs6000 / rs6000depend.sml < prev    next >
Encoding:
Text File  |  1993-01-27  |  8.4 KB  |  290 lines

  1. (** IBM RS6000 specific dependences **)
  2.  
  3. structure RS6000Depend : MACHINSTR = struct
  4.   structure M =  RS6000InstrSet
  5.   open M
  6.  
  7.   fun error msg = ErrorMsg.impossible ("RS6kDepend." ^ msg)
  8.  
  9.   val branchDelayedArch = false
  10.  
  11.   datatype ikind = IK_NOP | IK_JUMP | IK_INSTR
  12.  
  13.   fun isSdiBranch (M.BRANCH _)  = true
  14.     | isSdiBranch (M.FBRANCH _) = true
  15.     | isSdiBranch _         = false
  16.   
  17.   fun instrKind instr = 
  18.       case instr of 
  19.        M.NOP   => IK_NOP
  20.      | M.B _   => IK_JUMP
  21.      | M.BB _  => IK_JUMP
  22.      | M.BBF _ => IK_JUMP
  23.      | M.BR _  => IK_JUMP
  24.      | _       => IK_INSTR
  25.  
  26.   val nop = M.A(Reg 0,Reg 0,RegOp(Reg 0))
  27.  
  28.   fun minSize _ = 4
  29.  
  30.   fun sizeOf (info as INFO{addrOf,...}) (sdi,loc) = let
  31.       fun lab_value (lab,k) = M.labelValue info 
  32.                          (POSLAB lab,k-M.constBaseRegOffset)
  33.       fun is_short n = ~32768 <= n andalso n <= 32767
  34.       fun is_short_branch lab = let 
  35.           val const = addrOf lab - loc
  36.     in 
  37.         is_short (const div 4)
  38.         end
  39.     in
  40.     case sdi
  41.       of M.SETBASEADDR(lab,reg) => let
  42.              val const = M.constBaseRegOffset - addrOf lab
  43.          in 
  44.          if is_short const then (false, 4) else (true, 12)
  45.            end
  46.        | M.LOADADDR(_,lab,k) => 
  47.          if is_short(lab_value(lab,k)) then (false,4) else (true,12) 
  48.            | M.LOAD(_,lab,k) =>
  49.          if is_short(lab_value(lab,k)) then (false,4) else (true,12) 
  50.            | M.LOADF(_,lab,offset,_)  => let
  51.              val labexp1 = (POSLAB lab,offset-M.constBaseRegOffset)
  52.            val labexp2 = (POSLAB lab,offset-M.constBaseRegOffset+4)
  53.               val labval1 = M.labelValue info labexp1
  54.            val labval2 = M.labelValue info labexp2
  55.              in
  56.          if (is_short labval1 andalso is_short labval2) 
  57.          then (false,20)
  58.          else (true,32)
  59.              end
  60.            | M.BRANCH(_,_,lab,_,_) =>
  61.           if is_short_branch lab then (false,4) else (true,24)
  62.            | M.FBRANCH(_,_,_,lab,_,_) =>
  63.            if is_short_branch lab then (false,4) else (true,24)
  64.   end
  65.  
  66.   fun expand _ (sdi,size,loc) = 
  67.       case sdi of
  68.     M.SETBASEADDR(lab,reg) => 
  69.       let val labexp = (M.NEGLAB lab,M.constBaseRegOffset)
  70.       in case size of
  71.         4  => 
  72.             [M.A(M.baseReg,reg,M.LabelOp labexp)]
  73.           | 12 => 
  74.             [M.LIU(M.baseReg,M.HiLabOp labexp),
  75.              M.A(M.baseReg,M.baseReg,M.LoLabOp labexp),
  76.              M.A(M.baseReg,reg,RegOp M.baseReg)]
  77.           | _  => error "expand: SETBASEADDR"
  78.       end
  79.       | M.LOADADDR(r,lab,k) => 
  80.        let val labexp = (POSLAB lab,k-M.constBaseRegOffset)
  81.        in case size
  82.           of 4  => 
  83.              [M.A(r,M.baseReg,LabelOp labexp)]
  84.            | 12 =>  
  85.              [M.LIU(r,HiLabOp labexp),
  86.               M.A(r,r,LoLabOp labexp),
  87.               M.A(r,M.baseReg,RegOp r)]
  88.            | _  => error "expand: LOADADDR"
  89.        end
  90.       | LOAD(r,lab,k) => 
  91.        let val labexp = (POSLAB lab,k-M.constBaseRegOffset)
  92.        in case size
  93.           of 4  => [M.L(r,M.baseReg,LabelOp labexp)]
  94.            | 12 => [M.LIU(r,HiLabOp labexp),
  95.             M.A(r,M.baseReg,RegOp r),
  96.             M.L(r,r,LoLabOp labexp)]
  97.            | _ => error "expand: LOAD"
  98.        end
  99.       | M.LOADF(Freg fp,lab,offset,tmpR) => 
  100.        let val labexp1 = (POSLAB lab,offset-M.constBaseRegOffset)
  101.            val labexp2 = (POSLAB lab,offset-M.constBaseRegOffset+4)
  102.            val stackptr = Reg 1
  103.        in case size 
  104.         of 20  => 
  105.                [M.L(Reg 0,M.baseReg,LabelOp labexp1),
  106.             M.L(tmpR,M.baseReg,LabelOp labexp2),
  107.             M.ST(Reg 0,stackptr,Immed16Op M.fLoadStoreOff),
  108.             M.ST(tmpR,stackptr,Immed16Op(M.fLoadStoreOff+4)),
  109.             M.LFD(Freg fp,stackptr,Immed16Op M.fLoadStoreOff)]
  110.              | 32 => 
  111.                [M.LIU(tmpR,HiLabOp labexp1),
  112.             M.A(tmpR,tmpR,RegOp M.baseReg),
  113.             M.A(tmpR,tmpR,LoLabOp labexp1),
  114.             M.L(Reg 0,tmpR,Immed16Op 0),
  115.             M.ST(Reg 0,stackptr,Immed16Op(M.fLoadStoreOff)),
  116.             M.L(Reg 0,tmpR,Immed16Op 4),
  117.             M.ST(Reg 0,stackptr,Immed16Op(M.fLoadStoreOff+4)),
  118.             M.LFD(Freg fp,stackptr,Immed16Op M.fLoadStoreOff)]
  119.              | _ => error "expand: LOADF"
  120.        end
  121.       | M.BRANCH(cc,bool,tlab,tmpR,flab) => 
  122.        (case size
  123.         of 4  => [M.BB(cc,bool,Label16Off(POSLAB tlab,0))]
  124.  
  125.           | 24 => 
  126.           let val labexp = (POSLAB tlab,~M.constBaseRegOffset)
  127.           in
  128.               [M.BB(cc,not bool,Label16Off(POSLAB flab,0)),
  129.  
  130.                (** Could use a branch24 **)
  131.                M.LIU(tmpR,HiLabOp labexp),
  132.                M.A(tmpR,tmpR,LoLabOp labexp),
  133.                M.A(tmpR,tmpR,RegOp M.baseReg),
  134.                M.MTSPR(M.LR,tmpR),
  135.                M.BR ()]
  136.           end
  137.          | _ => error "expand: BRANCH")
  138.      | M.FBRANCH(cc,cr,bool,tlab,tmpR,flab) =>
  139.        (case size 
  140.               of 4 => [M.BBF(cc,cr,bool,Label16Off (POSLAB tlab,0))]
  141.            | 24 => 
  142.              let val labexp = (POSLAB tlab,~M.constBaseRegOffset)
  143.              in
  144.              [M.BBF(cc,cr,not bool,Label16Off(POSLAB flab,0)),
  145.  
  146.               M.LIU(tmpR,HiLabOp labexp),
  147.               M.A(tmpR,tmpR,LoLabOp labexp),
  148.               M.A(tmpR,tmpR,RegOp M.baseReg),
  149.               M.MTSPR(M.LR,tmpR),
  150.               M.BR ()]
  151.              end
  152.            | _ => error "expand: FBRANCH")
  153.      | _ => error "expand"
  154.  
  155.  
  156.  (*
  157.   * Resources: ($0-$31)+($f0,$f1-$f31)+cc+fcc+npc+LR+mem+fpscr+stack
  158.   *)
  159.  
  160.   val numResources = 71
  161.  
  162.   structure RId = struct
  163.      fun reg (Reg r) = [r] | reg _ = error "RId.reg"
  164.      fun fregd (Freg i) = [32 + i] | fregd _ = error "RId.fregd"
  165.      fun anyreg r = case r of Reg _ => reg r | Freg _ => fregd r
  166.      val cc      = 64
  167.      val fcc     = 65 
  168.      val npc    = 66 
  169.      val lr      = 67
  170.      val mem     = 68
  171.      val fpscr     = 69
  172.      val stack  = 70
  173.  
  174.      val Reg(alloc)    = M.allocReg (* resource no. for reg = reg no. *)
  175.      val Reg(exnptr)   = M.exnptrReg
  176.      val Reg(stackptr) = M.stackReg
  177.   end
  178.  
  179.   local 
  180.     open RId
  181.     fun is_allocR reg = reg = M.allocReg
  182.     fun is_stackR reg = reg = M.stackReg
  183.     fun arithOpndUse opnd = case opnd of RegOp r => RId.reg r | _ => []
  184.  
  185.     val allR = let fun f(~1,l) = l | f(i,l) = f(i-1,i::l)
  186.            in f(numResources-1,[])
  187.            end
  188.  
  189.     fun arith_ud(rd,rs,ea)    = (reg rs @ arithOpndUse ea, reg rd)
  190.     fun logical_ud(rd,rs,ea)  = (reg rs @ arithOpndUse ea, cc::reg rd)
  191.     fun logical_3reg_ud(rd,ra,rb)  
  192.                   = (reg ra @ reg rb, cc::reg rd)
  193.     fun double_cc_ud(fd,fs,ft)= (fregd fs @ fregd ft, cc::fregd fd)
  194.  
  195.     fun load_ud(rt,base,ea)   = let val u = anyreg base @ arithOpndUse ea
  196.                     val d = anyreg rt
  197.                 in 
  198.                     if is_stackR base then (stack::u,d)
  199.                     else (mem::u,d)
  200.                 end
  201.     fun store_ud(rt,base,ea)  = let val use = anyreg rt @ anyreg base @ 
  202.                           arithOpndUse ea
  203.                 in if is_stackR base then (use,[stack])
  204.                    else if is_allocR base then (use, []) 
  205.                     else (use,[mem])
  206.                 end
  207.     fun shift_ud(ra,rs,sh)    = let val (u,d) = (reg rs, reg ra)
  208.                 in case sh 
  209.                      of RegShift sh => (reg sh @ u, d)
  210.                       | _ => (u,d)
  211.                 end
  212.   in
  213.     fun rUseDef I = 
  214.     case I 
  215.         of NOP               => error "rUseDef: NOP"
  216.  
  217.          | M.B _         => ([],[npc])
  218.      | M.BB _         => ([lr,cc], [npc])
  219.      | M.BBF _         => ([lr,fcc],[npc])
  220.      | M.BR _         => ([lr],[npc])
  221.  
  222.      | M.LBZ arg         => load_ud arg
  223.      | M.L arg         => load_ud arg
  224.      | M.LFD arg         => load_ud arg
  225.      | M.LIU (rt,_)     => ([],RId.reg rt)
  226.      | M.MTSPR (M.LR,ra)     => (RId.reg ra,[lr])
  227.      | M.CAL arg        => arith_ud arg
  228.  
  229.      | M.STB arg         => store_ud arg
  230.      | M.ST    arg          => store_ud arg
  231.      | M.STFD arg         => store_ud arg
  232.  
  233.          | M.A(arg as (Reg rd,_, _)) => let
  234.              val (u,d) = arith_ud arg
  235.        in
  236.            if is_allocR (Reg rd) then (u,mem::d) else (u,d)
  237.            end  
  238.      | M.A _        => error "rUseDef: M.A"
  239.      | M.AO arg         => logical_3reg_ud arg
  240.      | M.FAO arg         => double_cc_ud arg
  241.  
  242.      | M.SF arg         => arith_ud arg
  243.      | M.SFO arg         => logical_3reg_ud arg
  244.      | M.FSO arg         => double_cc_ud arg
  245.  
  246.      | M.MULSO arg         => logical_3reg_ud arg
  247.      | M.FMO arg         => double_cc_ud arg
  248.  
  249.      | M.DIVS arg         => logical_3reg_ud arg
  250.        | M.FDO arg         => double_cc_ud arg
  251.  
  252.      | M.FNEG(ra,rb)    => (RId.fregd rb, fcc::RId.fregd ra)
  253.      | M.FABS(frt,frb)    => (RId.fregd frb, RId.fregd frt)
  254.  
  255.            | M.CMP(ra,ea)     => (reg ra @ arithOpndUse ea, [cc])
  256.      | M.CMPL(ra,rb)    => (reg ra @ reg rb, [cc])
  257.      | M.FCMP(fra,frb)     => (fregd fra @ fregd frb, [fcc])
  258.  
  259.          | M.AND arg         => logical_ud arg
  260.      | M.OR arg         => logical_ud arg
  261.      | M.XOR arg         => logical_ud arg
  262.      | M.XORU arg         => logical_ud arg
  263.  
  264.      | M.SL arg         => shift_ud arg
  265.      | M.SRA arg         => shift_ud arg
  266.  
  267.      | M.FMR(frt,frb)     => (RId.fregd frb, RId.fregd frt)
  268.          | M.MTFSB1 n         => ([], [fpscr])
  269.      | M.TRAP()         => ([fpscr,exnptr], [npc])
  270.   end
  271.  
  272.   fun latency (M.LBZ _)     = 2
  273.     | latency (M.L _)        = 2
  274.     | latency (M.LFD _)        = 2
  275.     | latency (M.CMP _)        = 3
  276.     | latency (M.CMPL _)    = 3
  277.     | latency (M.FCMP _)    = 8
  278.     | latency (M.MTSPR _)    = 4
  279.     | latency (M.FAO _)        = 2
  280.     | latency (M.FSO _)        = 2
  281.     | latency (M.FMO _)        = 2
  282.     | latency (M.FDO _)        = 2
  283.     | latency _            = 1
  284.  
  285.   fun mayNeedNop _ = 0
  286.  
  287.   fun needsNop _   = 0
  288. end 
  289.  
  290.